<template>
  <div v-if="props.docId" class="ml-4">
    <div class="header">
      <div>
        {{ title }}
      </div>
      <div>
        <a-button type="primary" size="small" :loading="loading" danger @click="send"
          >发起请求</a-button
        >
        <a-button
          size="small"
          style="margin-left: 5px; margin-right: 5px"
          :loading="loading"
          @click="reset"
          >重置请求</a-button
        >
      </div>
    </div>
    <div class="content">
      <div class="path">
        <div class="path_title">
          请求路径 : <span style="margin-left: 5px">{{ api.path }}</span>
        </div>
      </div>
      <div class="parameter">
        <div class="parameter_title">
          请求参数：
          <CodeEditor
            :value="requestParam"
            :mode="MODE.JSON"
            :onChange="paramChange"
          ></CodeEditor>
        </div>
      </div>
      <div class="response">
        <div class="response_title">
          响应信息：
          <JsonPreview :data="responseData"></JsonPreview>
        </div>
      </div>
    </div>
  </div>
</template>
<script lang="ts" setup name="Debug">
import { ref, nextTick, watch, onMounted } from "vue";
import { Description } from "/@/components/Description/index";
import { getApiDocDetail } from "/@/api/sys/api";
import { defHttp } from "/@/utils/http/axios";
import { h } from "vue";
import { CodeEditor, JsonPreview, MODE } from "/@/components/CodeEditor";
import { useMessage } from "/@/hooks/web/useMessage";

const activeKey = ref(["1"]);

const props = defineProps({
  docId: { type: String },
});
const title = ref("接口调试：未选择接口");
const api: any = ref({});
const { createMessage } = useMessage();

async function reload() {
  responseData.value = null;
  const result = await getApiDocDetail(props.docId!);
  api.value = result.data;
  title.value = "接口调试：" + result.data.name;
  paramRender(result.data.requestParam);
  reRenderFlag.value = true;
}

const loading = ref(false);
const reRenderFlag = ref(true);

const reset = async () => {
  loading.value = true;
  reRenderFlag.value = false;
  await reload();
  responseData.value = null;
  loading.value = false;
};

const requestParam: any = ref(null);
const responseData: any = ref();
const send = async () => {
  try {
    loading.value = true;
    const result = await defHttp.post({ url: api.value.path, data: requestParam.value });
    responseData.value = result;
  } catch (e) {
    // createMessage.warning("请求失败");
  } finally {
    loading.value = false;
  }
};

watch(
  () => props.docId,
  () => {
    nextTick(() => {
      reload();
    });
  }
);

const paramRender = (curVal) => {
  if (curVal) {
    const data: Object = JSON.parse(curVal);
    const keys: Array<string> = Object.keys(data);
    // 只有一个参数的情况
    if (keys.length === 1) {
      const param = data[keys[0]];
      const paramKeys: Array<string> = Object.keys(param);
      let result = {};
      paramKeys.forEach((key: string) => {
        if (param[key].detail) {
          if (param[key].type.startsWith("List")) {
            result[param[key].name] = [];
            let children = {};
            param[key].detail.forEach((child) => {
              children[child.name] = mockValue(child.type);
            });
            result[param[key].name].push(children);
          } else {
            param[key].detail.forEach((child) => {
              result[param[key].name][child.name] = mockValue(child.type);
            });
          }
        } else {
          result[param[key].name] = mockValue(param[key]);
        }
      });
      requestParam.value = result;
    }
    // 多个参数的情况，分开处理是因为获取到的参数名称是错误的，而且绝大多数都是一个参数
    else {
      let result: object = {};
      keys.forEach((key: string) => {
        const param = data[key];
        const paramKeys: Array<string> = Object.keys(param);
        let item = {};
        paramKeys.forEach((key: string) => {
          if (param[key].detail) {
            if (param[key].type.startsWith("List")) {
              item[param[key].name] = [];
              let children = {};
              param[key].detail.forEach((child) => {
                children[child.name] = mockValue(child.type);
              });
              item[param[key].name].push(children);
            } else {
              param[key].detail.forEach((child) => {
                item[param[key].name][child.name] = mockValue(child.type);
              });
            }
          } else {
            item[param[key].name] = mockValue(param[key]);
          }
        });
        result[key] = item;
      });
      requestParam.value = result;
    }
  } else {
    requestParam.value = {};
  }
};

// 渲染响应信息
const responseRender = () => () => {
  return h(JsonPreview, { data: responseData.value });
};

// 请求参数修改回调
const paramChange = (val) => {
  requestParam.value = val;
};

// 模拟请求参数
const mockValue = (item) => {
  if (item.type == "String") {
    return "";
  } else if (item.type == "Integer") {
    return 1;
  } else if (item.type == "LocalDate") {
    return "2024-01-01";
  } else if (item.type == "LocalDateTime") {
    return "2024-01-01 09:30:12";
  } else if (item.type == "Boolean") {
    return true;
  } else if (item.type == "List<String>") {
    return ["1", "2"];
  } else if (item.type == "List<Integer>") {
    return [1, 2];
  } else {
    return null;
  }
};
</script>
<style lang="less">
.header {
  width: 100%;
  height: 40px;
  line-height: 40px;
  background-color: #fff;
  padding-left: 10px;
  box-sizing: border-box;
  display: flex;
  justify-content: space-between;
  border-bottom: 1px solid #ccc;
  .down {
    margin-right: 10px;
  }
}

.content {
  width: 100%;
  background-color: #fff;
  box-sizing: border-box;
  padding-left: 10px;
  padding-right: 10px;
  .path {
    font-size: 14px;
    color: rgba(0, 0, 0, 0.88);
    display: flex;
    .path_title {
      width: 100%;
      height: 40px;
      line-height: 40px;
      background-color: #fafafa;
      border: 0.5px solid #ebebeb;
      margin-top: 5px;
      margin-bottom: 5px;
      box-sizing: border-box;
      padding-left: 10px;
      padding-right: 10px;
      border-radius: 5px;
    }
  }
  .parameter {
    font-size: 14px;
    color: rgba(0, 0, 0, 0.88);
    display: flex;
    .parameter_title {
      width: 100%;
      height: 100%;
      line-height: 40px;
      background-color: #fafafa;
      border: 0.5px solid #ebebeb;
      margin-top: 5px;
      margin-bottom: 5px;
      box-sizing: border-box;
      padding-left: 10px;
      padding-right: 10px;
      padding-bottom: 10px;
      border-radius: 5px;
    }
  }

  .response {
    font-size: 14px;
    color: rgba(0, 0, 0, 0.88);
    display: flex;
    .response_title {
      width: 100%;
      height: 100%;
      line-height: 40px;
      background-color: #fafafa;
      border: 0.5px solid #ebebeb;
      margin-top: 5px;
      margin-bottom: 5px;
      box-sizing: border-box;
      padding-left: 10px;
      padding-right: 10px;
      padding-bottom: 10px;
      border-radius: 5px;
    }
  }
}
</style>
